package common.mq.basic.service.impl;

import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import common.mq.basic.service.MessageService;
import common.mq.basic.util.MessageUtil;
import common.mq.po.ExceType;
import common.mq.po.MessType;
import common.mq.po.Message;
import common.mq.po.RepeatType;
import common.mq.po.TimingType;
import common.mq.register.po.MessageBase;
import common.mq.register.service.IRegisterService;

public class MessageServiceImpl implements MessageService {

	final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(MessageServiceImpl.class);
	
	@Autowired
	private IRegisterService registerService ;

	@Override
	public int gainNextTime(Message m) {
		if(m.getType() == null){
			return -1;
		}
		switch (m.getType()) {
		case TIMING:
		case SEQ:
			return MessageUtil.genNextTimeByTimingType(TimingType.DEFAULT, m);
		case EXC:
		case NORMAL:
			return MessageUtil.genNextTimeByExceType(ExceType.DEFAULT, m);
		default:
			log.warn("[gainNextTime] mess type message EXCE_TYPE not exist => "
					+ m.getType());
			return -1;
		}
	}

	@Override
	public boolean checkMessageFormat(Message m) {
		boolean res = true;
		//id不能为空
		if(m.getId() == null || m.getCategory() == null){
			log.info("[checkMessageFormat] msg => id or category is null | " + m.toString());
			res = false;
		}
		//类别名不在注册范围内
		if(!registerService.hasRegister(m.getCategory())){
			log.info("[checkMessageFormat] msg => category not in register | " + m.toString());
			res = false;
		}
		//消息已经过期
		int now = (int) new GregorianCalendar().getTimeInMillis() / 1000;
		if(now >= m.getOverdueTime()){
			log.info("[checkMessageFormat] msg => msg has overdued | " + m.toString());
			res = false;
		}
		if(m.getContent() == null){
			log.info("[checkMessageFormat] msg => msg 's getContent is null | " + m.toString());
			res = false;
		}
		//通过类别名查询注册表，得到该类别名对应消息内容的必填字段
		MessageBase msgBase = registerService.getMessageBase(m.getCategory());
		Map<String,String> contentBase = msgBase.getContent();
		//扫描消息内容，检查fields是否存在
		for(String f : contentBase.keySet()){
			//检查f在m.getContent中是否存在
			if(!m.getContent().containsKey(f)){
				log.info("[checkMessageFormat] msg => m's content no this key => " + f);
				res = false;
				continue;
			}
			String type = (String) contentBase.get(f);
			String v = m.getContent().get(f);
			//检查f对应的数据类型是否正确 java.lang.String
			if(type.equals("int")){
				try {
					Integer.parseInt(v);
				} catch (NumberFormatException e) {
					log.info("[checkMessageFormat] msg => field 's type  is wrong ! correct type is Integer " );
					res = false;
				}
			}else if(type.equals("string")){
					
			}else if(type.equals("bool")){
				try {
					//[1,0]
					int b = Integer.parseInt(v);
					if(b != 0 && b != 1){
						log.info("[checkMessageFormat] msg => field 's type  is wrong ! correct type is Boolean " );
						res = false;
					}
				} catch (NumberFormatException e) {
					log.info("[checkMessageFormat] msg => field 's type  is wrong ! correct type is Boolean " );
					res = false;
				}
			}else if(type.equals("list")){
				try {
					Gson gson = new Gson(); 
					gson.fromJson(v, List.class);
				} catch (JsonSyntaxException e) {
					log.info("[checkMessageFormat] msg => field 's type  is wrong ! correct type is List " );
					res = false;
				}  
			}else{
				log.info("[checkMessageFormat] msg => field 's type  is wrong ! type => " + type );
				res = false;
			}
		}
		return res;
	}

	@Override
	public Message cloneMessage(Message m) {
		return m.clone();
	}

	@Override
	public Message updateNextExecute(Message m, int nextTime) {
		if (m == null || nextTime == -1) {
			log.warn("[updateNextExecute] message is null ");
			return null;
		}
		m.setNextTime(nextTime);
		m.setCount(m.getCount() + 1);
		// 如果message's type 是普通，则修改为异常type
		if (m.getType() == MessType.NORMAL) {
			m.setType(MessType.EXC);
			m.setExceType(ExceType.DEFAULT);
		}
		return m;
	}

	@Override
	public Message genMessage(String category, int receiveTime, Map<String,String> content)  throws Exception{
		Message m = new Message();
		//根据category获取元消息
		MessageBase msgBase = registerService.getMessageBase(m.getCategory());
		if(msgBase == null){
			throw new Exception("msgBase is null , category => " + m.getCategory());
		}
		//使用UUID生成msgId
		 m.setId(UUID.randomUUID().toString()); 
		//将receiveTime赋值给Message
		m.setReceiveTime(receiveTime);
		m.setCategory(category);
		m.setContent(content);
		//计算失效时间
		int now = (int) new GregorianCalendar().getTimeInMillis() / 1000;
		m.setOverdueTime(now + msgBase.getOverdueTime());
		//设定类型
		m.setType(MessType.values()[msgBase.getType()]);
		m.setCount(1);
		//以下均设为默认值
		m.setRepeat(false);
		m.setExceType(ExceType.DEFAULT);
		m.setTimingType(TimingType.DEFAULT);
		m.setRepeatType(RepeatType.DEFAULT);
		return m;
	}

	public void setRegisterService(IRegisterService registerService) {
		this.registerService = registerService;
	}


}
